package com.dms.modules.community.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dms.common.api.ApiResponse;
import com.dms.common.exception.BusinessException;
import com.dms.common.security.SecurityUtils;
import com.dms.modules.community.dto.CommunityPostDTO;
import com.dms.modules.community.dto.CommunityPostDetailDTO;
import com.dms.modules.community.entity.CommunityPost;
import com.dms.modules.community.entity.CommunityPostTag;
import com.dms.modules.community.entity.CommunityTag;
import com.dms.modules.community.service.CommunityPostService;
import com.dms.modules.community.service.CommunityPostTagService;
import com.dms.modules.community.service.CommunityTagService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.security.access.prepost.PreAuthorize;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 社区帖子控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/community/posts")
@Api(tags = "社区帖子管理")
@RequiredArgsConstructor
@Validated
public class CommunityPostController {

    private final CommunityPostService postService;
    private final CommunityTagService tagService;
    private final CommunityPostTagService postTagService;

    /**
     * 获取当前登录用户ID
     */
    private Long getCurrentUserId() {
        return SecurityUtils.getCurrentUserId();
    }

    @PostMapping
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("发布帖子")
    public ApiResponse<Long> createPost(@Valid @RequestBody CommunityPostDTO postDTO) {
        try {
            Long userId = getCurrentUserId();
            Long postId = postService.createPost(postDTO, userId);
            return ApiResponse.success(postId);
        } catch (BusinessException e) {
            log.warn("发布帖子失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("发布帖子失败", e);
            return ApiResponse.error("发布帖子失败");
        }
    }

    @PutMapping("/{id}")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("更新帖子")
    public ApiResponse<Boolean> updatePost(
            @PathVariable @NotNull(message = "帖子ID不能为空") Long id,
            @Valid @RequestBody CommunityPostDTO postDTO) {
        Long userId = getCurrentUserId();
        boolean result = postService.updatePost(userId, id, postDTO);
        return ApiResponse.success(result);
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN') or (hasRole('USER') and @communitySecurityService.isPostOwner(#id))")
    @ApiOperation("删除帖子")
    public ApiResponse<Boolean> deletePost(@PathVariable @NotNull(message = "帖子ID不能为空") Long id) {
        try {
            Long userId = getCurrentUserId();
            boolean result = postService.deletePost(userId, id);
            if (!result) {
                return ApiResponse.notFound("帖子不存在或已被删除");
            }
            return ApiResponse.success(true);
        } catch (BusinessException e) {
            log.warn("删除帖子失败: postId={}, {}", id, e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("删除帖子失败: postId={}", id, e);
            return ApiResponse.error("删除帖子失败");
        }
    }

    @GetMapping("/{id}")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    @ApiOperation("获取帖子详情")
    public ApiResponse<CommunityPostDetailDTO> getPostDetail(
            @PathVariable @NotNull(message = "帖子ID不能为空") Long id) {
        Long userId = getCurrentUserId();
        CommunityPostDetailDTO postDetail = postService.getPostDetail(userId, id);
        if (postDetail == null) {
            return ApiResponse.notFound("帖子不存在");
        }
        return ApiResponse.success(postDetail);
    }

    @GetMapping
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    @ApiOperation(value = "获取帖子列表", notes = "不传userId或传入undefined获取全部帖子，传入userId获取指定用户的帖子")
    public ApiResponse<Page<CommunityPostDetailDTO>> getPostList(
            @RequestParam(required = false) String userId,
            @RequestParam(defaultValue = "1") @Min(value = 1, message = "页码不能小于1") Integer pageNum,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "每页条数不能小于1") Integer pageSize) {
        try {
            Long currentUserId = getCurrentUserId();
            Long targetUserId = null;
            if (userId != null && !"undefined".equals(userId)) {
                try {
                    targetUserId = Long.parseLong(userId);
                } catch (NumberFormatException e) {
                    log.warn("Invalid userId format: {}", userId);
                }
            }
            
            Page<CommunityPostDetailDTO> page = new Page<>(pageNum, pageSize);
            IPage<CommunityPostDetailDTO> result = postService.getPostList(currentUserId, page, targetUserId);
            return ApiResponse.success(convertToPage(result));
        } catch (Exception e) {
            log.error("获取帖子列表失败: userId={}, pageNum={}, pageSize={}", userId, pageNum, pageSize, e);
            return ApiResponse.error("获取帖子列表失败");
        }
    }

    @GetMapping("/my")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("获取我的帖子列表")
    public ApiResponse<Page<CommunityPostDetailDTO>> getMyPosts(
            @RequestParam(defaultValue = "1") @Min(value = 1, message = "页码不能小于1") Integer pageNum,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "每页条数不能小于1") Integer pageSize) {
        try {
            Long currentUserId = getCurrentUserId();
            Page<CommunityPostDetailDTO> page = new Page<>(pageNum, pageSize);
            IPage<CommunityPostDetailDTO> result = postService.getPostList(currentUserId, page, currentUserId);
            return ApiResponse.success(convertToPage(result));
        } catch (Exception e) {
            log.error("获取我的帖子列表失败: pageNum={}, pageSize={}", pageNum, pageSize, e);
            return ApiResponse.error("获取我的帖子列表失败");
        }
    }

    @PostMapping("/{id}/like")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("点赞帖子")
    public ApiResponse<Boolean> likePost(@PathVariable @NotNull(message = "帖子ID不能为空") Long id) {
        Long userId = getCurrentUserId();
        boolean result = postService.likePost(userId, id);
        return ApiResponse.success(result);
    }

    @DeleteMapping("/{id}/like")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("取消点赞帖子")
    public ApiResponse<Boolean> unlikePost(@PathVariable @NotNull(message = "帖子ID不能为空") Long id) {
        Long userId = getCurrentUserId();
        boolean result = postService.unlikePost(userId, id);
        return ApiResponse.success(result);
    }

    @PostMapping("/{id}/favorite")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("收藏帖子")
    public ApiResponse<Boolean> favoritePost(@PathVariable @NotNull(message = "帖子ID不能为空") Long id) {
        Long userId = getCurrentUserId();
        boolean result = postService.favoritePost(userId, id);
        return ApiResponse.success(result);
    }

    @DeleteMapping("/{id}/favorite")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("取消收藏帖子")
    public ApiResponse<Boolean> unfavoritePost(@PathVariable @NotNull(message = "帖子ID不能为空") Long id) {
        try {
            Long userId = getCurrentUserId();
            boolean result = postService.unfavoritePost(userId, id);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("取消收藏帖子失败: postId={}, {}", id, e.getMessage(), e);
            return ApiResponse.error(e);
        }
    }

    @GetMapping("/favorites")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    @ApiOperation("获取用户收藏的帖子列表")
    public ApiResponse<IPage<CommunityPostDetailDTO>> getFavoritePosts(
            @RequestParam(defaultValue = "1") @Min(value = 1, message = "页码不能小于1") Integer pageNum,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "每页条数不能小于1") Integer pageSize) {
        try {
            Long userId = getCurrentUserId();
            Page<CommunityPostDetailDTO> page = new Page<>(pageNum, pageSize);
            IPage<CommunityPostDetailDTO> favoritePosts = postService.getFavoritePosts(userId, page);
            return ApiResponse.success(favoritePosts);
        } catch (Exception e) {
            log.error("获取收藏帖子列表失败: pageNum={}, pageSize={}, {}", 
                    pageNum, pageSize, e.getMessage(), e);
            return ApiResponse.error(e);
        }
    }

    @PostMapping("/upload/image")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "上传帖子图片", notes = "支持jpg、png、gif格式，单个文件最大5MB")
    public ApiResponse<String> uploadImage(
            @ApiParam(value = "图片文件", required = true) 
            @RequestParam("file") MultipartFile file) {
        try {
            Long userId = getCurrentUserId();
            String imageUrl = postService.uploadImage(userId, file);
            return ApiResponse.success(imageUrl);
        } catch (Exception e) {
            log.error("上传帖子图片失败: ", e);
            return ApiResponse.error("上传图片失败：" + e.getMessage());
        }
    }

    @GetMapping("/tags")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    @ApiOperation("获取所有可用标签")
    public ApiResponse<List<CommunityTag>> getAllTags() {
        try {
            List<CommunityTag> tags = tagService.getAvailableTags();
            return ApiResponse.success(tags);
        } catch (Exception e) {
            log.error("获取标签列表失败: {}", e.getMessage(), e);
            return ApiResponse.error(e);
        }
    }

    @GetMapping("/tags/hot")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    @ApiOperation("获取热门标签")
    public ApiResponse<List<CommunityTag>> getHotTags(
            @RequestParam(defaultValue = "10") @Min(1) Integer limit) {
        try {
            List<CommunityTag> tags = tagService.getHotTags(limit);
            return ApiResponse.success(tags);
        } catch (Exception e) {
            log.error("获取热门标签失败: {}", e.getMessage(), e);
            return ApiResponse.error(e);
        }
    }

    @GetMapping("/tags/{tagId}")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    @ApiOperation("获取指定标签的帖子列表")
    public ApiResponse<Page<CommunityPostDetailDTO>> getPostsByTag(
            @PathVariable Long tagId,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            Long userId = getCurrentUserId();
            Page<CommunityPostDetailDTO> page = new Page<>(pageNum, pageSize);
            
            // 获取带有标签的帖子列表
            IPage<CommunityPostDetailDTO> result = postService.getPostsByTag(userId, page, tagId);
            return ApiResponse.success(convertToPage(result));
        } catch (Exception e) {
            log.error("获取标签帖子列表失败: tagId={}, pageNum={}, pageSize={}", 
                    tagId, pageNum, pageSize, e);
            return ApiResponse.error(e);
        }
    }

    /**
     * 将IPage转换为Page
     */
    private <T> Page<T> convertToPage(IPage<T> iPage) {
        if (iPage == null) {
            return null;
        }
        Page<T> page = new Page<>(iPage.getCurrent(), iPage.getSize(), iPage.getTotal());
        page.setRecords(iPage.getRecords());
        return page;
    }
} 